package com.ruicar.afs.cloud.batch.dayend.process;

import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruicar.afs.cloud.batch.dayend.handle.run.MessageProcessor;
import com.ruicar.afs.cloud.batch.dayend.handle.run.SystemJdbcConfig;
import com.ruicar.afs.cloud.batch.dayend.mq.BasicSender;
import com.ruicar.afs.cloud.batch.frame.AbsBatchRunner;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.util.SpringContextHolder;
import com.ruicar.afs.cloud.common.modules.contract.enums.ContractBusinessEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.MessageTemplateBusinessEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.PersonRoleTypeEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.YesOrNoEnum;
import com.ruicar.afs.cloud.common.modules.dto.mq.loan.contractdto.LoanActivateReceiveNoticeDTO;
import com.ruicar.afs.cloud.common.mq.rabbit.message.AfsTransEntity;
import com.ruicar.afs.cloud.common.mq.rabbit.message.MqTransCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.sql.*;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>Description: 短信任务</p>
 *
 * @author infinity
 * @version 1.0
 * @date 2020/9/18 10:50
 */
@Slf4j
public class ContractCloseBathRunner extends AbsBatchRunner {
    private  BasicSender basicSender= SpringContextHolder.getBean(BasicSender.class);
    private final StringBuffer sqlSms = new StringBuffer(" insert into basic_sms(id,contract_no,channel,code,uid,phone,template_id,estimated_time,sms_content,priority,origin ")
            .append(", dept_id,create_by,create_time ) values(?,?,?,?,?,?,?,?,?,?,? ,?,?,? ) ");
    //短信
    private final String SHORT_MSG = "short-msg";
    public static final int TOTAL_NUM = 200;
    private  SystemJdbcConfig systemJdbcConfig= SpringContextHolder.getBean(SystemJdbcConfig.class);
    public void process(String param) {
        Connection base = this.getConnection();
        logger.info("读取==={}", loadBreakPoint());
        Connection contract = this.getConnection(systemJdbcConfig.getBasic());
        Connection contractManage = this.getConnection(systemJdbcConfig.getManage());
        try {
            boolean isFinish = false;
            //获取短信模板信息
            Map map = SpringContextHolder.getBean(MessageProcessor.class).getSms(contractManage, SHORT_MSG, AfsEnumUtil.key(MessageTemplateBusinessEnum.CONTACT_CLOSE), AfsEnumUtil.key(YesOrNoEnum.yes));
            while (!isFinish) {
                log.info("处理短信信息--开始");
                String loadBreakPoint = loadBreakPoint();
                logger.info("读取==={}", loadBreakPoint);
                isFinish = handleContractClose(loadBreakPoint, contract, contractManage, map);
                log.info("处理短信信息--结束");
            }
            logger.info("读取==={}", loadBreakPoint());
        } catch (Exception e) {
            logger.error("", e);
            throw new AfsBaseException(e.getMessage());
        } finally {
            clean(base);
            clean(contract);
            clean(contractManage);
        }
    }

    /**
     * 合同关闭跑批:
     * 1.扫描manage_overpayment_difference表，查找close_date为空得，把close_date更新掉。
     * 同时basic_main_info表得close_date也更新。最后调用短信接口发送短信
     */
    private Boolean handleContractClose(String loadBreakPoint, Connection contract, Connection contractManage, Map map) {
        Long id = getId(loadBreakPoint);
        StringBuffer sqlOverpayment = new StringBuffer();
        sqlOverpayment.append("select overpayment.id,overpayment.contract_no   ");
        sqlOverpayment.append(" from manage_overpayment_difference overpayment ");
        sqlOverpayment.append(" where ifnull(overpayment.close_date,'no')='no'  ");
        if (id != null) {
            sqlOverpayment.append(" and overpayment.id> ? ");
        }
        sqlOverpayment.append(" order by overpayment.id asc  limit 0, ? ");

        //处理溢缴款、差额处理记录表
        StringBuffer updateOverpayment = new StringBuffer();
        updateOverpayment.append("update manage_overpayment_difference  set close_date=? where contract_no=? ");
        //处理合同信息
        StringBuffer updateContactInfo = new StringBuffer();
        updateContactInfo.append("update basic_main_info  set close_date=? where contract_no=? ");
        //放送短信信息
        StringBuffer sendSms = new StringBuffer();
        sendSms.append("select  relation.contract_no,info.cust_name,info.phone ");
        sendSms.append("from  basic_contract_cust_relation relation   ");
        sendSms.append("inner join basic_cust_base_info info on info.cust_no = relation.cust_no ");
        sendSms.append(" where  relation.cust_role=? and relation.contract_no  =?   ");
        PreparedStatement psSms = null;
        PreparedStatement psSendSms = null;
        ResultSet rsSendSms = null;
        PreparedStatement ps = null;
        PreparedStatement updateOverpaymentPs = null;
        PreparedStatement updateContactInfoPs = null;
        ResultSet rs = null;
        try {
            Date batchDate = new Date(batchDateInfo.getBatchDate().getTime());
            updateOverpaymentPs = contractManage.prepareStatement(updateOverpayment.toString());
            updateContactInfoPs = contract.prepareStatement(updateContactInfo.toString());
            psSms = contract.prepareStatement(sqlSms.toString());
            psSendSms = contract.prepareStatement(sendSms.toString());
            ps = contractManage.prepareStatement(sqlOverpayment.toString());
            if (id != null) {
                ps.setLong(1, id);
                ps.setInt(2, TOTAL_NUM);
            } else {
                ps.setInt(1, TOTAL_NUM);
            }
            rs = ps.executeQuery();
            int i = 0;
            while (rs != null && rs.next()) {
                String contractNo = rs.getString("contract_no");
                id = rs.getLong("id");
                //处理溢缴款、差额处理记录表
                handleOverpayment(updateOverpaymentPs, contractNo, batchDate);
                //处理合同信息
                handleContactInfo(updateContactInfoPs, contractNo, batchDate);
                //发送信息并推送mq
                handleSmsAndMq(map, psSms, psSendSms, rsSendSms, contractNo, batchDate);
                i++;
                psSms.executeBatch();
                updateOverpaymentPs.executeBatch();
                updateContactInfoPs.executeBatch();
                contractManage.commit();
                contract.commit();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("startId", id);
                saveBreakPoint(jsonObject.toString());
            }
            //短信已发送完毕
            if (i == 0) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new AfsBaseException(e.getMessage());
        } finally {
            clean(ps);
            clean(rs);
            clean(psSms);
            clean(rsSendSms);
            clean(psSendSms);
        }
    }

    /**
     * 处理短信
     *
     * @param map
     * @param psSms
     * @param rsSendSms
     * @param contractNo
     * @param batchDate
     */
    private void handleSmsAndMq(Map map, PreparedStatement psSms, PreparedStatement psSendSms, ResultSet rsSendSms, String contractNo, Date batchDate) throws SQLException {
        String phone = null;
        String name = null;
        Map valueMap = new HashMap();
        psSendSms.setString(1, AfsEnumUtil.key(PersonRoleTypeEnum.MAIN_PERSON));
        psSendSms.setString(2, contractNo);
        rsSendSms = psSendSms.executeQuery();
        if (rsSendSms != null && rsSendSms.next()) {
            name = rsSendSms.getString("cust_name");
            phone = rsSendSms.getString("phone");
            SpringContextHolder.getBean(MessageProcessor.class).saveSms(psSms, map, phone, contractNo, name, valueMap, batchDate);


            LoanActivateReceiveNoticeDTO dto = new LoanActivateReceiveNoticeDTO();
            dto.setContractNo(contractNo);
            dto.setCaseDate(batchDate);
            dto.setCaseType(ContractBusinessEnum.closeContract);
            AfsTransEntity<LoanActivateReceiveNoticeDTO> afsTransEntity = new AfsTransEntity<>();
            afsTransEntity.setData(dto);
            afsTransEntity.setTransCode(MqTransCode.AFS_CONTRACT_BASIC_CASE_CTM_ACTIVATION_STATUS);
            basicSender.sendContractBasicToCtmCase(afsTransEntity);
        }else{
            throw new AfsBaseException(MessageFormat.format("合同号:{0},数据不存在！",contractNo));
        }
    }

    /**
     * 处理合同信息
     * @param updateContactInfoPs
     * @param contractNo
     * @param batchDate
     */
    private void handleContactInfo(PreparedStatement updateContactInfoPs, String contractNo, Date batchDate) throws SQLException {
        updateContactInfoPs.setDate(1, batchDate);
        updateContactInfoPs.setString(2, contractNo);
        updateContactInfoPs.addBatch();
    }

    /**
     * 处理溢缴款、差额处理记录表
     *
     * @param updateOverpaymentPs
     * @param contractNo
     * @param batchDate
     */
    private void handleOverpayment(PreparedStatement updateOverpaymentPs, String contractNo, Date batchDate) throws SQLException {
        updateOverpaymentPs.setDate(1, batchDate);
        updateOverpaymentPs.setString(2, contractNo);
        updateOverpaymentPs.addBatch();
    }

    //获取断点id
    private Long getId(String loadBreakPoint) {
        if (StringUtil.isBlank(loadBreakPoint)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(loadBreakPoint);
        Long startId = (Long) jsonObject.get("startId");
        return startId;
    }
}
